//=====================================================================================
/** \file biketimer.cc
 *	  This file contains a program which will hopefully someday make a timer work on 
 *	  an ME405 board with an ATmega128. This comment should be more detailed when a
 *	  complete program is here. It is the student's responsibility to put something
 *	  sensible here. Turning in code with this nonsense for a comment would be bad. 
 *
 *  Revisions
 *    \li 01-05-2008 JRR Original file
 *    \li 01-04-2009 JRR Upgraded to use latest versions of base classes
 *    \li 03-30-2008 JRR Another upgrade to latest versions
 *    \li 01-??-20?? ??? Whoever did this assignment NEEDS TO CHANGE THIS COMMENT
 */
//=====================================================================================

											// System headers included with < >
#include <stdlib.h>							// Standard C library
#include <avr/io.h>							// Input-output ports, special registers
#include <avr/interrupt.h>					// Interrupt handling functions

											// User written headers included with " "
#include "rs232int.h"						// Serial port header
#include "stl_timer.h"						// Microsecond-resolution (approx.) timer


//-------------------------------------------------------------------------------------
/** The main function is the "entry point" of every C program, the one which runs first
 *  (after standard setup code has finished). For mechatronics programs, main() creates
 *  a bunch of objects, sets them up, then runs an infinite loop and never exits.
 *  @return Although a mechatronics program never returns (there's no OS to return to),
 *          we generally have to return something, say 0, to keep the compiler happy.
 */

int main ()
{
	volatile unsigned int dummy = 0;		// Delay loop counters should be voltile
	char input_char;						// A character typed by the user

	// Create a serial port object. The time will be printed to this port, which
	// should be hooked up to a dumb terminal program like minicom on a PC
	rs232 the_serial_port (9600, 0);

	// Create a time stamp object. This is a data structure which holds measured times
	time_stamp the_time;

	// Create another time stamp, and fill it with a time reading of zero
	time_stamp zero_time (0L);

	// Create a task timer object. Though normally used to time tasks, this timer can
	// also be used just to keep track of the time
	task_timer the_timer;

	// Print a greeting message. This is almost always a good thing because it lets 
	// the user know that the program is actually running
	the_serial_port << endl << "AVR Timer(not yet) V0.1" << endl;

	// Enable interrupts. This is necessary because the timer uses a timer interrupt
	sei ();

	// Configure Port C pin 2 as an input with its pullup resistor turned on.
	// DDRC is the data direction register, and PORTC is the output register,
	// which in this case enables the pullup resistor (AVR's have no PUCRx)
	// WARNING: Check the documentation for the Ministrone board if you are using it!
	// The port and pin numbers are different for that board (try Port D).
	DDRC &= ~0b00000100;
	PORTC |= 0b00000100;

	// Run the main scheduling loop, in which the action to run is done repeatedly.
	// In the future, we'll run tasks here; for now, just do things in a simple loop
	while (true)
	{
		// Check if the user has typed something. If it's a 'c', clear the counter to
		// a reading of zero; if not, show that the program is confused
		if (the_serial_port.check_for_char ())
		{
			input_char = the_serial_port.getchar ();
			if (input_char == 'c')
			{
				the_timer.set_time (zero_time);
				the_serial_port << endl << "Clearing timer" << endl;
			}
			else
			{
				the_serial_port << "?" << endl;
			}
		}

		// The dummy counter is used to slow down the rate at which stuff is printed
		// on the terminal
		if (++dummy >= 10000)
		{
			dummy = 0;

			// Check I/O port C pin 2. To read pins, one must read PINC, as PORTC is
			// the name of the output register, not the input from the pins
			if (PINC & 0b00000100)
				the_serial_port << "[1] ";
			else
				the_serial_port << "[0] ";
	
			// Print the current time, then a carriage return with no linefeed 
			the_serial_port << the_timer.get_time_now () << "\r";
		}
	}

	return (0);
}
